home *** CD-ROM | disk | FTP | other *** search
/ Nautilus 1992 July / Nautilus-3-8 / Nautilus-3-8.bin / Tools & Utilities / Techy Stuff / Source ƒ / Filelist ƒ / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-14  |  14.3 KB  |  657 lines

  1. /*
  2.     FileList 1.4
  3.     "Main.c"
  4. */
  5.  
  6. #define GLOBALS
  7. #include "Main.h"
  8. #include "Utilities.h"
  9. #include "File.h"
  10. #include "Mouse.h"
  11. #include "Stack.h"
  12. #include "Search.h"
  13. #include "Window.h"
  14. #include "About.h"
  15. #include "Options.h"
  16. #include "Init.h"
  17.  
  18. /* ----- Used by InitDialogs() ----------------------------------------- */
  19.  
  20. pascal void Crash (void)
  21. {
  22.     ExitToShell();
  23. }
  24.  
  25. /* ----- Error message ------------------------------------------------- */
  26.  
  27. void Message (
  28.     register short n,
  29.     register short code)
  30. {
  31.     register StringHandle h;
  32.     register DialogPtr dialogP;
  33.     short item;
  34.     unsigned char number[10];
  35.  
  36.     InitCursor();
  37.     SysBeep(1);
  38.     if (h = GetString(n)) {
  39.         HLock(h);
  40.         if (code)
  41.             NumToString((long)code, number);
  42.         else
  43.             number[0] = 0;
  44.         ParamText(*h, number, EmptyStr, EmptyStr);
  45.         CenterDialog('DLOG', MessageDialog);
  46.         if (dialogP = GetNewDialog(MessageDialog, 0L, -1L)) {
  47.             ModalDialog(0L, &item);
  48.             DisposDialog(dialogP);
  49.         }
  50.         HUnlock(h);
  51.     }
  52. }
  53.  
  54. /* ----- Save Alert ---------------------------------------------------- */
  55.  
  56. Boolean SaveBefore (void)
  57. {
  58.     register unsigned char *s;
  59.  
  60.     if (!Dirty)
  61.         return TRUE;
  62.     if (VrefNum)
  63.         s = Fname;
  64.     else
  65.         s = *GetString(SAVENAME);
  66.     ParamText(s, EmptyStr, EmptyStr, EmptyStr);
  67.     CenterDialog('ALRT', SaveDialog);
  68.     switch (CautionAlert(SaveDialog, 0L)) {
  69.         case SaveOk:
  70.             if (!DoSave(FALSE))
  71.                 return FALSE;    /* Cancel */
  72.         case SaveNo:
  73.             return TRUE;
  74.     }
  75.     return FALSE;    /* Cancel */
  76. }
  77.  
  78. /* ----- Update menus -------------------------------------------------- */
  79.  
  80. #define MS_WINDOW    0x0001    /* There is at least one window */
  81. #define MS_ACTIVE    0x0002    /* We are active */
  82. #define MS_DATA        0x0004    /* There is data */
  83. #define MS_DIRTY    0x0008    /* The data is dirty */
  84. #define MS_VOLUME    0x0010    /* A volume is selected */
  85. #define MS_SELECT    0x0020    /* A volume/file is selected */
  86. #define MS_AGAIN    0x0040    /* Find again is possible */
  87.  
  88. static void EnableMenu (register MenuHandle mh, register short n)
  89. {
  90.     while (n > 0) {
  91.         EnableItem(mh, n);
  92.         --n;
  93.     }
  94. }
  95.  
  96. static void DisableMenu (register MenuHandle mh, register short n)
  97. {
  98.     while (n > 0) {
  99.         DisableItem(mh, n);
  100.         --n;
  101.     }
  102. }
  103.  
  104. static void UpdateMenus (register short options)
  105. {
  106.     register WindowData *w;
  107.     register short state;
  108.  
  109.     options &= optionKey;
  110.     state = 0;
  111.     if (w = (WindowDataPtr)FrontWindow()) {
  112.         state |= MS_WINDOW;
  113.         if (w == &FileData || w == &VolumeData) {
  114.             state |= MS_ACTIVE;
  115.             if (InfoSize) {
  116.                 state |= MS_DATA;
  117.                 if (Dirty)
  118.                     state |= MS_DIRTY;
  119.                 if (VolumeData.select != -1L && w == &VolumeData) {
  120.                     state |= MS_VOLUME;
  121.                     state |= MS_SELECT;
  122.                 } else
  123.                     if (FileData.select != -1L && w == &FileData)
  124.                         state |= MS_SELECT;
  125.                 if (w->find[0] || w->type || w->creator)
  126.                     state |= MS_AGAIN;
  127.              }
  128.         }
  129.     }
  130.  
  131.     if (state & MS_WINDOW)
  132.         if (state & MS_ACTIVE) {    /* We are active */
  133.             EnableItem(FileM, fOpen);
  134.             DisableItem(EditM, eUndo);
  135.             DisableItem(EditM, eCut);
  136.             DisableItem(EditM, ePaste);
  137.             EnableMenu(VolumeM, vItems);
  138.             if (state & MS_DATA) {    /* Data */
  139.                 if (options)
  140.                     EnableItem(EditM, eClear);
  141.                 else
  142.                     DisableItem(EditM, eClear);
  143.                 EnableItem(FileM, fNew);
  144.                 EnableItem(FileM, fSaveAs);
  145.                 EnableItem(FileM, fSaveText);
  146.                 EnableMenu(FileData.sortmenu, FSORT_MAX);
  147.                 EnableItem(EditM, eFind);
  148.                 if (state & MS_AGAIN)
  149.                     EnableItem(EditM, eAgain);
  150.                 else
  151.                     DisableItem(EditM, eAgain);
  152.                 EnableMenu(VolumeData.sortmenu, VSORT_MAX);
  153.                 if (state & MS_DIRTY)
  154.                     EnableItem(FileM, fSave);
  155.                 else
  156.                     DisableItem(FileM, fSave);
  157.                 if (state & MS_VOLUME) {
  158.                     EnableItem(VolumeM, vDelete);
  159.                     EnableItem(VolumeM, vRename);
  160.                 } else {
  161.                     DisableItem(VolumeM, vDelete);
  162.                     DisableItem(VolumeM, vRename);
  163.                 }
  164.                 if (state & MS_SELECT){
  165.                     EnableItem(EditM, eCopy);
  166.                     EnableItem(EditM, eSelection);
  167.                 } else {
  168.                     DisableItem(EditM, eCopy);
  169.                     DisableItem(EditM, eSelection);
  170.                 }
  171.             } else {    /* No data */
  172.                 DisableItem(FileM, fNew);
  173.                 DisableItem(FileM, fSave);
  174.                 DisableItem(FileM, fSaveAs);
  175.                 DisableItem(FileM, fSaveText);
  176.                 DisableItem(EditM, eCopy);
  177.                 DisableItem(EditM, eClear);
  178.                 DisableItem(EditM, eFind);
  179.                 DisableItem(EditM, eAgain);
  180.                 DisableItem(EditM, eSelection);
  181.                 DisableItem(VolumeM, vDelete);
  182.                 DisableItem(VolumeM, vRename);
  183.                 DisableMenu(FileData.sortmenu, FSORT_MAX);
  184.                 DisableMenu(VolumeData.sortmenu, VSORT_MAX);
  185.             }
  186.         } else {    /* Desk accessory window */
  187.             DisableItem(FileM, fNew);
  188.             DisableItem(FileM, fOpen);
  189.             DisableItem(FileM, fSave);
  190.             DisableItem(FileM, fSaveAs);
  191.             DisableItem(FileM, fSaveText);
  192.             EnableItem(EditM, eUndo);
  193.             EnableItem(EditM, eCut);
  194.             EnableItem(EditM, eCopy);
  195.             EnableItem(EditM, ePaste);
  196.             EnableItem(EditM, eClear);
  197.             DisableItem(EditM, eFind);
  198.             DisableItem(EditM, eAgain);
  199.             DisableItem(EditM, eSelection);
  200.             DisableItem(VolumeM, 0);
  201.             DisableMenu(FileData.sortmenu, FSORT_MAX);
  202.             DisableMenu(VolumeData.sortmenu, VSORT_MAX);
  203.         }
  204.     else {    /* No window */
  205.         DisableItem(FileM, fNew);
  206.         DisableItem(FileM, fOpen);
  207.         DisableItem(FileM, fSave);
  208.         DisableItem(FileM, fSaveAs);
  209.         DisableItem(FileM, fSaveText);
  210.         DisableMenu(EditM, eItems);
  211.         DisableItem(VolumeM, vItems);
  212.         DisableMenu(FileData.sortmenu, FSORT_MAX);
  213.         DisableMenu(VolumeData.sortmenu, VSORT_MAX);
  214.     }
  215. }
  216.  
  217. /* ----- Close Window -------------------------------------------------- */
  218.  
  219. void DoClose (register WindowPeek w)
  220. {
  221.     register short k;
  222.  
  223.     if ((k = w->windowKind) < 0)
  224.         CloseDeskAcc(k);
  225.     else
  226.         CloseWindow(w);
  227. }
  228.  
  229. void DoClose1 (register WindowPtr w)
  230. {
  231.     if (w == (WindowPtr)&FileData || w == (WindowPtr)&VolumeData)
  232.         SendBehind(w, 0L);
  233.     else
  234.         DoClose((WindowPeek)w);
  235. }
  236.  
  237. /* ----- Clear sorted by ----------------------------------------------- */
  238.  
  239. void ClearSorted (register WindowDataPtr w)
  240. {
  241.     if (w->sorted) {
  242.         CheckItem(w->sortmenu, w->sorted, FALSE);
  243.         w->sorted = 0;
  244.     }
  245. }
  246.  
  247. /* ----- Update window titles ------------------------------------------ */
  248.  
  249. void NewTitle (register WindowDataPtr w)
  250. {
  251.     register StringHandle h;
  252.     unsigned char num[10];
  253.     unsigned char t[256];
  254.  
  255.     if (h = GetString(w->title)) {
  256.         BlockMove(*h, t, **h + 1L);
  257.         NumToString(w->count, num);
  258.         Append(t, SpStr);
  259.         Append(t, num);
  260.         SetWTitle(w, t);
  261.     }
  262. }
  263.  
  264. /* ----- Update -------------------------------------------------------- */
  265.  
  266. static void UpdateW (register WindowDataPtr w)
  267. {
  268.     SetPort(w);
  269.     AdjustScrollBar(w);
  270.     SetCtlValue(w->vs, w->count - 1);        /* Scroll to end */
  271.     InvalRect(&((WindowPtr)w)->portRect);
  272.     NewTitle(w);
  273. }
  274.  
  275. void Update (void)
  276. {
  277.     UpdateW(&VolumeData);
  278.     UpdateW(&FileData);
  279. }
  280.  
  281. /* ----- Handle disk inserted event ------------------------------------ */
  282.  
  283. static void DoDisk (unsigned long message)
  284. {
  285.     register short err;
  286.  
  287.     if (err = SearchVol((short)(message & 0x0000FFFF), TRUE))
  288.         Message(err, 0);
  289.     Update();
  290.     ClearSorted(&FileData);
  291.     ClearSorted(&VolumeData);
  292.     Dirty = TRUE;
  293. }
  294.  
  295. /* ----- Sort window --------------------------------------------------- */
  296.  
  297. static void DoSort (
  298.     register WindowDataPtr w,
  299.     short item)
  300. {
  301.     register short i;
  302.  
  303.     if (item < 1 || item > w->maxsort)
  304.         return;
  305.     SetWatch();
  306.     w->sorted = item;
  307.     if (w->select != -1L)
  308.         Select(w, w->select, FALSE);
  309.     (*(w->sort))(item - 1);
  310.     for (i = 1; i <= w->maxsort; i++)
  311.         CheckItem(w->sortmenu, i, i == item);
  312.     SetPort(w);
  313.     AdjustScrollBar(w);
  314.     InvalRect(&((WindowPtr)w)->portRect);
  315.     Dirty = TRUE;
  316.     InitCursor();
  317. }
  318.  
  319. /* ----- Quit ---------------------------------------------------------- */
  320.  
  321. void DoQuit (void)
  322. {
  323.     DisposeMemory();
  324.     DoClose((WindowPeek)&FileData);
  325.     DoClose((WindowPeek)&VolumeData);
  326.     notQuiting = FALSE;
  327. }
  328.  
  329. /* ----- Activate Event ------------------------------------------------ */
  330.  
  331. static void DoActivate (
  332.     register WindowDataPtr w,
  333.     register short active)
  334. {
  335.     SetPort(w);
  336.     DrawGrowIcon(w);
  337.     DrawSelection(w);
  338.     active = active ? 0 : 255;
  339.     if (w->vs)
  340.         HiliteControl(w->vs, active);
  341.     if (w->hs)
  342.         HiliteControl(w->hs, active);
  343. }
  344.  
  345. /* ----- Handle menu command ------------------------------------------- */
  346.  
  347. static void DoMenuBar (
  348.     long info,
  349.     short modifiers)
  350. {
  351.     register theMenu = (info >> 16) & 0xFF;
  352.     register theItem = info & 0xFF;
  353.     register short i;
  354.     Str255    daName;
  355.     GrafPtr    temp;
  356.     long grow;
  357.     pascal long MaxMem();
  358.  
  359.     switch (theMenu) {
  360.         case AppleMenu:
  361.             if (theItem == aAbout)
  362.                 DoAbout(modifiers, MaxMem(&grow));
  363.             else {
  364.                 GetItem(AppleM, theItem, &daName);
  365.                 GetPort(&temp);
  366.                 OpenDeskAcc(&daName);
  367.                 SetPort(&temp);
  368.             }
  369.             break;
  370.         case FileMenu:
  371.             switch (theItem) {
  372.                 case fNew:
  373.                     if (SaveBefore()) {
  374.                         FileData.count = VolumeData.count = 
  375.                             InfoSize = InfoCount = 0L;
  376.                         VolumeData.select = FileData.select = -1L;
  377.                         Update();
  378.                         ClearSorted(&FileData);
  379.                         ClearSorted(&VolumeData);
  380.                         Dirty = FALSE;
  381.                         VrefNum = 0;
  382.                         FileData.vrefnum = VolumeData.vrefnum = 0;
  383.                     }
  384.                     break;
  385.                 case fOpen:
  386.                     DoOpen();
  387.                     break;
  388.                 case fClose:
  389.                     DoClose1(FrontWindow());
  390.                     break;
  391.                 case fSave:
  392.                     DoSave(FALSE);
  393.                     break;
  394.                 case fSaveAs:
  395.                     DoSave(TRUE);
  396.                     break;
  397.                 case fSaveText:
  398.                     DoSaveText((WindowDataPtr)FrontWindow());
  399.                     break;
  400.                 case fWindow:
  401.                     RestoreWindow(&VolumeData);
  402.                     RestoreWindow(&FileData);
  403.                     break;
  404.                 case fOptions:
  405.                     DoOptions(modifiers);
  406.                     break;
  407.                 case fQuit:
  408.                     if (SaveBefore()) {
  409.                         DoQuit();
  410.                         SetWatch();
  411.                     }
  412.                     break;
  413.             }
  414.             break;
  415.         case EditMenu:
  416.             switch (theItem) {
  417.                 case eUndo:
  418.                 case eCut:
  419.                 case ePaste:
  420.                     SystemEdit(theItem-1);
  421.                     break;
  422.                 case eCopy:
  423.                     if (!SystemEdit(theItem-1))
  424.                         CopySelection((WindowDataPtr)FrontWindow());
  425.                     break;
  426.                 case eClear:
  427.                     if (!SystemEdit(theItem-1))
  428.                         NoSort();
  429.                     break;
  430.                 case eFind:
  431.                     Find();
  432.                     break;
  433.                 case eAgain:
  434.                     Again();
  435.                     break;
  436.                 case eSelection:
  437.                     Selection();
  438.                     break;
  439.             }
  440.             break;
  441.         case FSortMenu:
  442.             DoSort(&FileData, theItem);
  443.             break;
  444.         case VSortMenu:
  445.             DoSort(&VolumeData, theItem);
  446.             break;
  447.         case VolumeMenu:
  448.             switch (theItem) {
  449.                 case vAuto:
  450.                     CheckItem(VolumeM, vAuto, Automatic = !Automatic);
  451.                     break;
  452.                 case vAdd:
  453.                     AddVolumes();
  454.                     break;
  455.                 case vDelete:
  456.                     DeleteVolume();
  457.                     break;
  458.                 case vRename:
  459.                     RenameVolume();
  460.                     break;
  461.             }
  462.             break;
  463.     }
  464.     HiliteMenu(0);
  465. }
  466.  
  467. /* ----- Key press event ----------------------------------------------- */
  468.  
  469. static void DoKeyDowns (register EventRecord *myEvent)
  470. {
  471.     register unsigned char ch;
  472.     register WindowDataPtr w = (WindowDataPtr)FrontWindow();
  473.     register Boolean option;
  474.  
  475.     ch = myEvent->message & charCodeMask;
  476.     if (myEvent->modifiers & cmdKey) {
  477.         UpdateMenus(myEvent->modifiers);
  478.         DoMenuBar(MenuKey(ch), myEvent->modifiers);
  479.         return;
  480.     }
  481.     switch (ch) {
  482.         case 0x05:                            /* Help */
  483.             DoMenuBar((unsigned long)AppleMenu << 16 | aAbout,
  484.                 myEvent->modifiers);
  485.             return;
  486.         case 0x10:                            /* Function key */
  487.             switch ((unsigned char)(myEvent->message >> 8)) {
  488.                 case 0x7A:                    /* F1: undo */
  489.                     DoMenuBar((unsigned long)EditMenu << 16 | eUndo,
  490.                         myEvent->modifiers);
  491.                     break;
  492.                 case 0x78:                    /* F2: cut */
  493.                     DoMenuBar((unsigned long)EditMenu << 16 | eCut,
  494.                         myEvent->modifiers);
  495.                     break;
  496.                 case 0x63:                    /* F3: copy */
  497.                     DoMenuBar((unsigned long)EditMenu << 16 | eCopy,
  498.                         myEvent->modifiers);
  499.                     break;
  500.                 case 0x76:                    /* F4: paste */
  501.                     DoMenuBar((unsigned long)EditMenu << 16 | ePaste,
  502.                         myEvent->modifiers);
  503.                     break;
  504.             }
  505.             return;
  506.     }
  507.  
  508.     if (w != &VolumeData && w != &FileData)        /* Not our problem */
  509.         return;
  510.     option = (myEvent->modifiers & optionKey) != 0;
  511.     switch (ch) {
  512.         case 0x03:                            /* Enter, return */
  513.         case 0x0D:
  514.             if (w->select != -1)
  515.                 Selection();
  516.             break;
  517.         case 0x01:                            /* Home */
  518.             MoveToLine(w, 0);
  519.             break;
  520.         case 0x04:                            /* End */
  521.             MoveToLine(w, w->count - 1);
  522.             break;
  523.         case 0x0B:                            /* Page up */
  524.             KeyScroll(w, TRUE, inPageUp);
  525.             break;
  526.         case 0x0C:                            /* Page down */
  527.             KeyScroll(w, TRUE, inPageDown);
  528.             break;
  529.         case 0x1C:                            /* Cursor left */
  530.             KeyScroll(w, FALSE, option ? inPageUp : inUpButton);
  531.             break;
  532.         case 0x1D:                            /* Cursor right */
  533.             KeyScroll(w, FALSE, option ? inPageDown : inDownButton);
  534.             break;
  535.         case 0x1E:                            /* Cursor up */
  536.             KeyScroll(w, TRUE, option ? inPageUp : inUpButton);
  537.             break;
  538.         case 0x1F:                            /* Cursor down */
  539.             KeyScroll(w, TRUE, option ? inPageDown : inDownButton);
  540.             break;
  541.     }
  542. }
  543.  
  544. /* ----- Handle mouse event -------------------------------------------- */
  545.  
  546. static void DoMouse (register EventRecord *myEvent)
  547. {
  548.     register Point        global;
  549.     register short        where;
  550.     WindowPtr            w;
  551.     
  552.     global = myEvent->where;
  553.     where = FindWindow(global, &w);
  554.     switch (where) {
  555.         case inDesk:
  556.             SysBeep(1);
  557.             break;
  558.         case inMenuBar:
  559.             UpdateMenus(myEvent->modifiers);
  560.             DoMenuBar(MenuSelect(global), myEvent->modifiers);
  561.             break;
  562.         case inSysWindow:
  563.             SystemClick(myEvent, w);
  564.             break;
  565.         case inContent:
  566.             DoContent(myEvent, w);
  567.             break;
  568.         case inDrag:
  569.             DragWindow(w, global, &Bounds);
  570.             break;
  571.         case inGrow:
  572.             DoGrow(w, global);
  573.             break;
  574.         case inGoAway:
  575.             if (TrackGoAway(w, global))
  576.                 DoClose1(w);
  577.             break;
  578.         case inZoomIn:
  579.         case inZoomOut:
  580.             if (TrackBox(w, global, where))
  581.                 DoZoom(w, where);
  582.     }
  583. }
  584.  
  585. /* ----- Update event -------------------------------------------------- */
  586.  
  587. static void DoUpdates (register EventRecord *myEvent)
  588. {
  589.     register WindowPtr w;
  590.     register WindowDataHdl h;
  591.     
  592.     w = (WindowPtr)(myEvent->message);
  593.     SetPort(w);
  594.     BeginUpdate(w);
  595.     EraseRect(&w->portRect);
  596.     RedrawV((WindowDataPtr)w, TRUE) /*RedrawH(w, TRUE)*/;
  597.     DrawGrowIcon(w);
  598.     DrawControls(w);
  599.     EndUpdate(w);
  600. }
  601.  
  602. /* ----- Main event loop ----------------------------------------------- */
  603.  
  604. static short Event (void)
  605. {
  606.     EventRecord event;
  607.     register Boolean doit;
  608.     register short active;
  609.     register WindowPeek    w;
  610.     
  611.     if (WNE)
  612.         doit = WaitNextEvent(everyEvent, &event, 300, 0L);
  613.     else {
  614.         SystemTask();
  615.         doit = GetNextEvent(everyEvent, &event);
  616.     }
  617.     if (doit) {
  618.         InitCursor();
  619.         switch (event.what) {
  620.             case mouseDown:
  621.                 DoMouse(&event);
  622.                 break;
  623.             case autoKey:
  624.             case keyDown:
  625.                 DoKeyDowns(&event);
  626.                 break;
  627.             case updateEvt:
  628.                 DoUpdates(&event);
  629.                 break;
  630.             case diskEvt:
  631.                 if (Automatic)
  632.                     DoDisk(event.message);
  633.                 break;
  634.             case activateEvt:
  635.                 active = event.modifiers & activeFlag;
  636.                 DoActivate((WindowDataPtr)event.message, active);
  637.                 break;
  638.             case app4Evt:            /* MultiFinder event */
  639.                 if ((w = (WindowPeek)FrontWindow()) &&
  640.                     (w->windowKind == userKind))
  641.                     DoActivate((WindowDataPtr)w,
  642.                     (Boolean)(event.message & 1));
  643.         }
  644.     }
  645.     return notQuiting;
  646. }
  647.  
  648. /* ----- Main program -------------------------------------------------- */
  649.  
  650. void main (void)
  651. {
  652.     MaxApplZone();
  653.     Init();
  654.     while (Event())
  655.         ;
  656. }
  657.